package org.jeecg.modules.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.bicycle.order.entity.BikeVehicleOrder;
import org.jeecg.modules.bicycle.order.mapper.BikeVehicleOrderMapper;
import org.jeecg.modules.client.GetuiPush;
import org.jeecg.modules.common.service.CommonMethodService;
import org.jeecg.modules.constant.BikeConstant;
import org.jeecg.modules.dto.other.DeviceHeartbeatReq;
import org.jeecg.modules.param.member.entity.BikeMemberUser;
import org.jeecg.modules.param.member.mapper.BikeMemberUserMapper;
import org.jeecg.modules.param.pile.entity.BikePile;
import org.jeecg.modules.param.pile.mapper.BikePileMapper;
import org.jeecg.modules.param.pile.service.IBikePileService;
import org.jeecg.modules.param.station.entity.BikeStation;
import org.jeecg.modules.param.station.entity.BikeStationHeartbeat;
import org.jeecg.modules.param.station.mapper.BikeStationHeartbeatMapper;
import org.jeecg.modules.param.station.mapper.BikeStationMapper;
import org.jeecg.modules.param.sysparam.entity.BikeSysParam;
import org.jeecg.modules.param.sysparam.mapper.BikeSysParamMapper;
import org.jeecg.modules.system.allsmslog.entity.BikeSysSmsLog;
import org.jeecg.modules.system.allsmslog.service.BikeSysSmsLogService;
import org.jeecg.modules.system.messagelog.entity.BikeSysMessageLog;
import org.jeecg.modules.system.messagelog.mapper.BikeSysMessageLogMapper;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 月月鸟
 * 自动提醒
 *
 * @author message
 */
@Slf4j
@Component
public class BikeQuartz implements Job {
    @Resource
    private BikeVehicleOrderMapper bikeVehicleOrderMapper;
    @Resource
    private BikeMemberUserMapper bikeMemberUserMapper;
    @Resource
    private BikeSysMessageLogMapper bikeSysMessageLogMapper;
    @Resource
    private BikeSysParamMapper bikeSysParamMapper;
    @Resource
    private CommonMethodService commonMethodService;
    @Resource
    private BikeStationMapper bikeStationMapper;
    @Resource
    private BikeStationHeartbeatMapper bikeStationHeartbeatMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private IBikePileService bikePileService;
    @Resource
    private BikePileMapper bikePileMapper;

    @Autowired
    private BikeSysSmsLogService bikeSysSmsLogService;

    @Autowired
    private GetuiPush getuiPush;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        outOrderTime1();
        outOrderTime2();
    }

    /**
     * 超时2小时未还车提醒
     */
    public void outOrderTime1() {
        //当前时间
        Date date = new Date();
        long time = date.getTime();
        //获取免费时长
        BikeSysParam bikeSysParam = bikeSysParamMapper.selectOne(new QueryWrapper<BikeSysParam>().eq("p_name", "param008"));
        time = time - Integer.parseInt(bikeSysParam.getPValue()) * 60000 ;
        //免费时间
        Date freeTime = new Date(time);
        //免费时间 提醒
        Date freeTime1 = new Date(time+ 600000);
        //查询未还车并用车时间超过2小时的订单
        QueryWrapper<BikeVehicleOrder> wrapper = new QueryWrapper<>();
        wrapper.isNull("park_time");
        //借车时间 小于 免费时间超时提醒时间        例如 免费提醒接车 17：00  免费接车 16：50  接车大于免费
        wrapper.le("pick_time",freeTime1);
        //借车时间 大于 免费时间超时提醒时间
        wrapper.ge("pick_time",freeTime);
        wrapper.isNull("stop_time");
        List<BikeVehicleOrder> bikeVehicleOrders = bikeVehicleOrderMapper.selectList(wrapper);
        if (bikeVehicleOrders.size() != 0) {
            //查询启用短信模板
            String messageTemplateByCode = commonMethodService.getMessageTemplateByCode(BikeConstant.park_free_time_code);
            String msg = commonMethodService.getMessageTemplateByCode(BikeConstant.park_free_time_msg_code);

            if (StringUtils.isNotEmpty(messageTemplateByCode)) {
                for (BikeVehicleOrder tb : bikeVehicleOrders) {
                    BikeMemberUser memberUser = bikeMemberUserMapper.selectById(tb.getPickUser());
                    if (memberUser != null) {
                        //查找是否有记录
                        QueryWrapper<BikeSysMessageLog> sml = new QueryWrapper<>();
                        //手机号
                        sml.eq("phone", memberUser.getCode());
                        //来源ID
                        sml.eq("remind_source", tb.getId());
                        //提醒类型 为 自动提醒超时
                        sml.eq("remind_type", "1");
                        Integer selectCount = bikeSysMessageLogMapper.selectCount(sml);
                        if (selectCount == 0) {
                            SMSDmeo.sendMessage(memberUser.getCode(), msg);
                            getuiPush.PushMsg(memberUser.getCode(),msg);
                            BikeSysMessageLog newBikeSysMessageLog = new BikeSysMessageLog();
                            newBikeSysMessageLog.setPhone(memberUser.getCode());
                            newBikeSysMessageLog.setRemindSource(tb.getId());
                            //自动提醒超时
                            newBikeSysMessageLog.setRemindType("1");
                            newBikeSysMessageLog.setMessage(messageTemplateByCode);
                            bikeSysMessageLogMapper.insert(newBikeSysMessageLog);
                            //发送短信记录
                            BikeSysSmsLog bikeSysSmsLog = new BikeSysSmsLog();
                            bikeSysSmsLog.setCreateBy("系统");
                            bikeSysSmsLog.setType("8");
                            bikeSysSmsLog.setMobile(memberUser.getCode());
                            bikeSysSmsLog.setContent(messageTemplateByCode);
                            bikeSysSmsLogService.add(bikeSysSmsLog);
                            commonMethodService.addSysMessages(memberUser.getId(), memberUser.getCode(), "借车超时提醒", messageTemplateByCode);
                        }
                    }
                }
            }
        }
    }

    /**
     * 超时3小时提醒
     */
    public void outOrderTime2() {
        //当前时间
        Date date = new Date();
        long time = date.getTime();
        BikeSysParam bikeSysParam = bikeSysParamMapper.selectOne(new QueryWrapper<BikeSysParam>().eq("p_name", "param008"));
        time = time - Integer.parseInt(bikeSysParam.getPValue()) * 60000;
        //收费时间 3小时
        Date freeTime = new Date(time-3600000);
        //提醒2级收费 用车时长 2.50小时
        Date freeTime1 = new Date(time-3000000);

        //查询未还车并用车时间超过2小时的订单
        QueryWrapper<BikeVehicleOrder> wrapper = new QueryWrapper<>();
        wrapper.isNull("park_time");
        //借车时间 小于 2小时+50分钟
        wrapper.le("pick_time", freeTime1);
        //大于 3小时
        wrapper.ge("pick_time",freeTime);
        wrapper.isNull("stop_time");
        List<BikeVehicleOrder> bikeVehicleOrders = bikeVehicleOrderMapper.selectList(wrapper);
        if (bikeVehicleOrders.size() != 0) {
            //查询启用短信模板
            String messageTemplateByCode = commonMethodService.getMessageTemplateByCode(BikeConstant.park_serious_time_code);
            if (StringUtils.isNotEmpty(messageTemplateByCode)) {
                for (BikeVehicleOrder tb : bikeVehicleOrders) {
                    BikeMemberUser memberUser = bikeMemberUserMapper.selectById(tb.getPickUser());
                    if (memberUser != null) {
                        //查找是否有记录
                        QueryWrapper<BikeSysMessageLog> sml = new QueryWrapper<>();
                        //手机号
                        sml.eq("phone", memberUser.getCode());
                        //来源ID
                        sml.eq("remind_source", tb.getId());
                        //提醒类型 为 自动提醒严重超时
                        sml.eq("remind_type", "2");
                        Integer selectCount = bikeSysMessageLogMapper.selectCount(sml);
                        if (selectCount == 0) {
                            //SMSDmeo.sendMessage(memberUser.getCode(), messageTemplateByCode);

                            getuiPush.PushMsg(memberUser.getCode(),messageTemplateByCode);

                            BikeSysMessageLog newBikeSysMessageLog = new BikeSysMessageLog();
                            newBikeSysMessageLog.setPhone(memberUser.getCode());
                            newBikeSysMessageLog.setRemindSource(tb.getId());
                            //自动提醒严重超时
                            newBikeSysMessageLog.setRemindType("2");
                            newBikeSysMessageLog.setMessage(messageTemplateByCode);
                            bikeSysMessageLogMapper.insert(newBikeSysMessageLog);
                            commonMethodService.addSysMessages(memberUser.getId(), memberUser.getCode(), "借车超时提醒", messageTemplateByCode);
                        }
                    }
                }
            }
        }
    }

    public void getHeartbeatByRedis() {
        List<BikeStation> isRegister = bikeStationMapper.selectList(new QueryWrapper<BikeStation>().eq("is_register", BikeConstant.y_n_yes));
        for (BikeStation tb : isRegister) {
            boolean b = redisUtil.hasKey(tb.getCode());
            if (b) {
                Map o = (Map) redisUtil.get(tb.getCode());
                DeviceHeartbeatReq bikeStationHeartbeat = new DeviceHeartbeatReq();
                bikeStationHeartbeat.setStationCode(tb.getCode());
                bikeStationHeartbeat.setTemperature((Float) o.get("temperature"));
                bikeStationHeartbeat.setHumidity((Float) o.get("humidity"));
                bikeStationHeartbeat.setVoltage((Float) o.get("voltage"));
                bikeStationHeartbeat.setLongitude((Double) o.get("longitude"));
                bikeStationHeartbeat.setLatitude((Double) o.get("latitude"));
                bikeStationHeartbeat.setLocationStatus((Integer) o.get("locationStatus"));
                bikeStationHeartbeat.setStationStatus((String) o.get("stationStatus"));
                deviceHeartbeatBusiness(bikeStationHeartbeat, tb);
            }
        }
    }

    public void deviceHeartbeatBusiness(DeviceHeartbeatReq deviceHeartbeatReq, BikeStation bikeStation) {

        // 1:获取请求参数
        String stationCode = deviceHeartbeatReq.getStationCode();
        float temperature = deviceHeartbeatReq.getTemperature();
        float humidity = deviceHeartbeatReq.getHumidity();
        float voltage = deviceHeartbeatReq.getVoltage();
        DecimalFormat df = new DecimalFormat("#.######");
        Double longitude = Double.parseDouble(df.format(deviceHeartbeatReq.getLongitude()));
        Double latitude = Double.parseDouble(df.format(deviceHeartbeatReq.getLatitude()));
        // 网点状态
        String statusString = bikeStation.getStatus();
        int locationStatus = deviceHeartbeatReq.getLocationStatus();


        // 如果网点是自动获取定位，则更新网点信息
        if (bikeStation.getIsLocation().equals(BikeConstant.y_n_yes) && locationStatus == 1) {
            bikeStation.setLongitude(String.valueOf(longitude));
            bikeStation.setLatitude(String.valueOf(latitude));
            bikeStationMapper.updateById(bikeStation);
        }

        // 3.注册车桩数据
        QueryWrapper<BikePile> pileWrapper = new QueryWrapper<>();
        pileWrapper.eq("station_id", bikeStation.getId());
        List<BikePile> bikePileList = bikePileMapper.selectList(pileWrapper);
        for (int i = 0; i < bikePileList.size(); i++) {
            BikePile bikePile = bikePileList.get(i);
            // 车桩版本放在心跳里面更新
            bikePile.setVersionCode(deviceHeartbeatReq.getPileVersion());
        }
        // 批量更新车桩数据
        bikePileService.updateBatchById(bikePileList);
        DecimalFormat format = new DecimalFormat("#.0");
        // 4；查询心跳包记录
        QueryWrapper<BikeStationHeartbeat> heartbeatWrapper = new QueryWrapper<>();
        heartbeatWrapper.eq("station_id", bikeStation.getId());
        BikeStationHeartbeat heartbeat = bikeStationHeartbeatMapper.selectOne(heartbeatWrapper);
        if (heartbeat == null) {
            heartbeat = new BikeStationHeartbeat();
            heartbeat.setStationId(bikeStation.getId());
            heartbeat.setTemperature(Double.valueOf(format.format(temperature)));
            heartbeat.setHumidity(Double.valueOf(format.format(humidity)));

            heartbeat.setVoltage(Double.valueOf(format.format(voltage)));
            heartbeat.setLongitude(longitude);
            heartbeat.setLatitude(latitude);
            heartbeat.setStationStatus(statusString);
            heartbeat.setLocationStatus(String.valueOf(locationStatus));
            bikeStationHeartbeatMapper.insert(heartbeat);
        } else {
            heartbeat.setTemperature(Double.valueOf(format.format(temperature)));
            heartbeat.setHumidity(Double.valueOf(format.format(humidity)));
            heartbeat.setVoltage(Double.valueOf(format.format(voltage)));
            heartbeat.setLongitude(longitude);
            heartbeat.setLatitude(latitude);
            heartbeat.setStationStatus(statusString);
            heartbeat.setLocationStatus(String.valueOf(locationStatus));
            bikeStationHeartbeatMapper.updateById(heartbeat);
        }

    }

}
